/*
 * Copyright (c) 2006, Second Life Reverse Engineering Team
 * All rights reserved.
 *
 * - Redistribution and use in source and binary forms, with or without
 *   modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this
 *   list of conditions and the following disclaimer.
 * - Neither the name of the Second Life Reverse Engineering Team nor the names
 *   of its contributors may be used to endorse or promote products derived from
 *   this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Collections.Generic;
using slcl.Packets;

namespace slcl
{
    /// <summary>
    /// Class for controlling various system settings.
    /// </summary>
    public class Settings
    {
        // These are specific to your app!!! Please set them accordingly if you override ANYTHING.
        public string VERSION = "0.0.1";
        public string LIBNAME = "slcl";
        public string AUTHOR = "brianw@terrabox.com";

        /// <summary>
        /// the dictionary of grids that we know about.
        /// </summary>
        public Dictionary<string, Dictionary<string, string>> Grids = new Dictionary<string, Dictionary<string, string>>();

        /// <summary>Maximum size of packet that we want to send over the wire</summary>
        public readonly int MAX_PACKET_SIZE = 1200;
        /// <summary>Millisecond interval between ticks, where all ACKs are 
        /// sent out and the age of unACKed packets is checked</summary>
        public readonly int Grid_TICK_LENGTH = 250;
        /// <summary>The maximum value of a packet sequence number. After that 
        /// we assume the sequence number just rolls over? Or maybe the 
        /// protocol isn't able to sustain a connection past that</summary>
        public readonly int MAX_SEQUENCE = 0xFFFFFF;
        /// <summary>Number of milliseconds before a teleport attempt will time
        /// out</summary>
        public readonly int TELEPORT_TIMEOUT = 25 * 1000;

        /// <summary>
        /// If true, each Manager get's it's own thread for processing things. 
        /// This allows the Client to be able to respond more smoothly to events.
        /// </summary>
        public bool USE_INDEPENDANT_QUEUES = true;

        /// <summary>Number of milliseconds before GridManager.Logout() will time out</summary>
        public int LOGOUT_TIMEOUT = 5 * 1000;

        /// <summary>Number of milliseconds for xml-rpc to timeout</summary>
        public int LOGIN_TIMEOUT = 60 * 1000;

        /// <summary>
        /// timeout for our caps requests.
        /// </summary>
        public int CAPS_TIMEOUT = 30 * 1000;
        /// <summary>The maximum size of the sequence number inbox, used to
        /// check for resent and/or duplicate packets</summary>
        public int INBOX_SIZE = 100;
        /// <summary>Milliseconds before a packet is assumed lost and resent</summary>
        public int RESEND_TIMEOUT = 4000;
        /// <summary>Milliseconds without receiving a packet before the 
        /// connection to a simulator is assumed lost</summary>
        public int SIMULATOR_TIMEOUT = 5 * 1000;
        /// <summary>Maximum number of queued ACKs to be sent before SendAcks()
        /// is forced</summary>
        public int MAX_PENDING_ACKS = 10;
        /// <summary>Maximum number of ACKs to append to a packet</summary>
        public int MAX_APPENDED_ACKS = 10;
        /// <summary>Cost of uploading an asset</summary>
        public int UPLOAD_COST { get { return priceUpload; } }
        /// <summary>Enable/disable debugging log messages</summary>
        public bool DEBUG = true;
        /// <summary>Attach avatar names to log messages</summary>
        public bool LOG_NAMES = true;
        /// <summary>Enable/disable storing terrain heightmaps in the TerrainManager</summary>
        public bool STORE_LAND_PATCHES = false;

        /// <summary>Enable/disable sending periodic camera updates</summary>
        public bool SEND_AGENT_UPDATES = true;

        /// <summary>Number of milliseconds between sending camera updates</summary>
        public int AGENT_UPDATE_INTERVAL = 500;
        /// <summary>
        /// how often do we update our position based on direction and speed?
        /// </summary>
        public const int INTERPOLATION_UPDATE = 250;

        /// <summary>Enable/disable slcl automatically setting the
        /// bandwidth throttle after connecting to each simulator</summary>
        /// <remarks>The default slcl throttle uses the equivalent of
        /// the maximum bandwidth setting in the official client. If you do not
        /// set a throttle your connection will by default be throttled well
        /// below the minimum values and you may experience connection problems</remarks>
        public bool SEND_AGENT_THROTTLE = true;
	public bool OUTBOUND_THROTTLE = false;
        /// <summary>Maximum outgoing bytes/sec, per sim</summary>
        public int OUTBOUND_THROTTLE_RATE = 1500;
        /// <summary>Grid stats queue length (seconds)</summary>
        public int STATS_QUEUE_SIZE = 5;
        /// <summary>Enable/disable the sending of pings to monitor lag and packet loss</summary>
        public bool SEND_PINGS = true;
        /// <summary>Number of milliseconds between sending pings to each sim</summary>
        public int PING_INTERVAL = 2200;
        /// <summary>If this is true, connection will be killed if we stop receiving pongs</summary>
		public bool USE_WATCHDOG = false;
	/// <summary>Number of seconds to wait for pong before killing</summary>
//		public int WATCHDOG_SECONDS = 10;
	/// <summary>Do we want to be able to cross sim borders?  (Experimental)</summary>
	    public bool CROSS_BORDERS = true;
        public bool MULTIPLE_SIMS = false;

        private Client Client;
        private int priceUpload = 0;

        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="client">Client connection Object to use</param>
        public Settings(Client client)
        {
            Client = client;
// FIXME            Client.Grid.RegisterCallback(Packets.PacketType.EconomyData, new GridManager.PacketCallback(EconomyDataHandler));
        }

        /// <summary>
        /// Presumably for outputting asset upload costs.
        /// </summary>
        /// <param name="packet"></param>
        /// <param name="simulator"></param>
        private void EconomyDataHandler(Packet packet, Simulator simulator)
        {
            EconomyDataPacket econ = (EconomyDataPacket)packet;

            priceUpload = econ.Info.PriceUpload;
        }
    }
}
